/**
 *  @author 侯庆峰, 15/12/16.
 *
 *  @name LTHttpOperation.h
 *
 *  @brief Set curl operation.
 *
 *  @copyright © 2015年 letv. All rights reserved.
 */

#ifndef LTHttpOperation_h
#define LTHttpOperation_h

#include <iostream>
#include <map>
#include <string>
#include <mutex>
#include <condition_variable>
#include "curl/curl.h"
using namespace std;

#define CurlRequestHandler long

/**
 *  请求回调函数
 *
 *  @param LTCurlCallback
 */
typedef void (*LTCurlCallback)(void     *buffer,
                               size_t   datalength,
                               bool     success,
                               void     *context);

/**
 * 请求类型
 */
enum RequestType{
    getRequest = 1,
    postRequest
};

class LTHttpOperation{
public:
    /**
     *  Construct Function
     */
    LTHttpOperation();
    
    /**
     *  Cancel Request
     */
    bool CancelRequest();
    
    /**
     *  Get Request
     */
    CurlRequestHandler GetRequest(const char *url,
                                  long urlLength,
                                  long timeout,
                                  map<string, string> &httpheader,
                                  void *context,
                                  char *proxy,
                                  long proxyLength,
                                  LTCurlCallback callc);
    
    /**
     *  Post Request
     */
    CurlRequestHandler PostRequest(const char *url,
                                   long urlLength,
                                   long timeout,
                                   map<string, string> &httpheader,
                                   void *context,
                                   void *postdata,
                                   long postlength,
                                   char *proxy,
                                   long proxyLength,
                                   LTCurlCallback callc);
public:
    /**
     *  Get Url
     */
    char *GetUrl();
    
    /**
     *  Get Curl
     */
    CURL *GetCurl();
    
    /**
     *  Get Proxy
     */
    char *getProxy();
    
    /**
     *  Get Timeout
     */
    long GetTimeout();
    
    /**
     *  Set Request id
     */
    long SetRequestID();
    
    /**
     *  Get Request id
     */
    long GetRequestID();
    
    /**
     *  Get Context
     */
    void *GetContext();
    
    /**
     *  Set isDeleted
     */
    void SetIsDeleted();
    
    /**
     *  Get isDeleted
     */
    bool GetIsDeleted();
    
    /**
     *  Get PostData
     */
    void *GetPostData();
    
    /**
     * Get Buffer
     */
    char *GetBufferData();
    
    /**
     *  Get PostDataLength
     */
    long GetPostDataLength();
    
    /**
     *  Get Buffer length
     */
    size_t GetBufferDataLength();
    
    /**
     *  Get CallBack
     */
    LTCurlCallback &GetCallBack();
    
    /**
     *  Get HttpHeaderList
     */
    struct curl_slist *GetHttpHeader();
    
    /**
     * Set Proxy
     */
    void setProxy(char *proxy, long length);
    
public:
    /**
     *  析构函数
     */
    virtual ~LTHttpOperation();
    
protected:
    /**
     *  初始化curl句柄
     */
    bool InitCurl();
    
    /**
     *  Set Url
     */
    bool SetUrl(char *url, long length);
    
    /**
     *  Set curl参数
     */
    void SetCurlParameter();
    
    /**
     *  Set curl通用参数
     */
    void SetCurlCommonParameter();
    
    /**
     *  Set Timeout
     */
    bool SetTimeout(long timeout);
    
    /**
     *   Set Context
     */
    void SetContext(void *context);
    
    /**
     *  Set Post Data
     */
    void SetPostData(void *postdata,long postlength);
    
    /**
     *  Set Post data Length
     */
    bool SetPostDataLength(long postlength);
    
    /**
     *  Set 回调函数
     */
    bool SetCallBack(LTCurlCallback callc);
    
    /**
     *  Set HttpHeader
     */
    bool SetHttpHeader(map<string, string> &httpheader);
    
    /**
     *  设置通用参数
     */
    void SetCommonParamter(const char *url,
                           long urlLength,
                           long timeout,
                           map<string, string> &httpheader,
                           void *context,
                           char *proxy,
                           long proxyLength,
                           LTCurlCallback callc);
    
    /**
     *  curl回调函数
     */
    static size_t curlCallc(void *buffer,
                            size_t size,
                            size_t length,
                            void *context);
    
    /**
     *  operation 类回调函数
     */
    size_t operationCallc(void *buffer,
                          size_t size,
                          size_t length,
                          void *context);
    
private:
    bool InitState;//初始化是否成功
    void *context; //
    CURL *curl;//curl句柄
    char *url;//url 地址
    long timeout;//连接超时时间
    map<string, string>httpHeader;//http报文头map
    struct curl_slist *headerList;//http报文头list（curl类型）
    void *postData;//post数据
    long postDataLength;//post数据长度
    LTCurlCallback callBack;//回调函数
    RequestType requestType;//请求类型
    static int requestID;//请求id，记录请求标志
    char *bufferData;//服务器返回数据缓存
    size_t bufferDataLength;//缓存数据长度
    char *proxy;//代理服务器地址
    bool isDeleted;//设置删除标志
    mutex requestHandlerMutex;
    int operationId;
};

#endif /* LTHttpOperation_h */